#!/bin/bash -e

if [ "$1" == help ]; then
 echo The following are expected modes of builds:
 echo $0 : Defaults to force build
 echo $0 inline : Builds missing containers, with results shown inline
 echo $0 ignore : Ignore any actual building, but reset hashes.
 echo $0 check : Check if the built images are updated.
 echo $0 push : Pushes images to docker hub
 echo $0 pull : Pulls images from docker hub
 echo $0 build : Builds only missing docker images
 echo $0 force [version] : Builds all docker images
 exit 0
fi

# Set this so docker build will fail even though piped through tee.
set -o pipefail

ROOT=$(dirname $0)/..
TAG_VER=`git describe || echo unknown`

force=force
inline=
DOCKER_IMAGE_LIST=docker_images.txt
DOCKER_IMAGE_VER=docker_images.ver

cd $ROOT
source misc/config_base.sh
host_tests=$host_tests bin/docker_build_files
function pull_images {
    TAG=$1
    declare -A test_set
    for target in $(host_tests=$host_tests bin/docker_build_files); do
        target=$(echo $target | sed 's|^.*/Dockerfile.||' | echo daqf/$(</dev/stdin))
        test_set[$target]=y
    done
    cat misc/$DOCKER_IMAGE_LIST | while read image hash other; do
        if [ -z "${test_set[$image]}" ]; then
            echo Skipping $image pull 
            continue
        fi 
        echo Pulling $image:$TAG from dockerhub...
        (docker pull $image:$TAG && docker tag $image:$TAG $image:latest) || echo "Could not pull $image:$VERSION."
    done 
}

if [ "$1" == push ]; then
    if [ ! -f inst/$DOCKER_IMAGE_VER ]; then
	echo Missing build version file, do force build with desired version.
	false
    fi
    NEWVER=$(< inst/$DOCKER_IMAGE_VER)
    cat inst/$DOCKER_IMAGE_LIST | while read image hash other; do
        found=$(docker images $image | awk '{print $3}' | grep $hash) || true
        if [ -z "$found" ]; then
            echo $image:$hash not found locally...
            continue
        fi
	docker tag $image:$hash $image:$NEWVER
        echo Push $image:$NEWVER to dockerhub...
        bin/docker_push $image $NEWVER
    done
    echo Updating misc/$DOCKER_IMAGE_LIST for version $NEWVER
    cp inst/$DOCKER_IMAGE_LIST misc/$DOCKER_IMAGE_LIST
    cp inst/$DOCKER_IMAGE_VER misc/$DOCKER_IMAGE_VER
    echo Done with docker build push.
    exit 0
elif [ "$1" == pull ]; then
    REPO_VER=$(< misc/$DOCKER_IMAGE_VER)
    REPO_HASH=`git rev-list -n 1 $REPO_VER`
    TAG_HASH=`git rev-list -n 1 $TAG_VER`
    if [ "$TAG_HASH" != "$REPO_HASH" ]; then
	echo Tagged version $TAG_VER does not match misc/$DOCKER_IMAGE_VER $REPO_VER
	false
    fi
    echo Pulling images for version $REPO_VER
    pull_images $REPO_VER
    echo Updating .build_hash
    bin/build_hash write
    mv -f .build_files .build_built
    echo Done with docker build pull.
    exit 0
elif [ "$1" == check ]; then
    shift
    bin/build_hash check
    exit 0
elif [ "$1" == build ]; then
    force=
    shift
elif [ "$1" == force ]; then
    if [ -n "$2" ]; then
	echo Setting build version to $2
	BUILD_IMAGE_VER=$2
	shift
    fi
    force=force
    shift
elif [ "$1" == inline ]; then
    inline="inline"
    shift
elif [ "$1" == ignore ]; then
    bin/build_hash write
    exit 0
elif [ "$1" == "" ]; then
    echo Defaulting to force build
else
    echo Unknown command $1
    false
fi

rm -f inst/$DOCKER_IMAGE_LIST
rm -f inst/$DOCKER_IMAGE_VER

if [ -n "$BUILD_IMAGE_VER" ]; then
    echo $BUILD_IMAGE_VER > inst/$DOCKER_IMAGE_VER
fi

local_version=$(cd faucet; git rev-list -n 1 HEAD)
if [ "$1" == -f ]; then
    echo Forcing misc/FAUCET_VERSION to $local_version
    echo $local_version > misc/FAUCET_VERSION
    shift
fi

target_version=$(cat misc/FAUCET_VERSION)
target_commit=$(cd faucet; git rev-parse $target_version)
if [ "$target_commit" != "$local_version" ]; then
    echo Local faucet commit is at: $local_version
    echo Mismatch with misc/FAUCET_VERSION: $target_version
    echo Try 'bin/clean_dev && bin/setup_dev' to reset.
    false
fi

bin/docker_build $force $inline

echo Updating inst/$DOCKER_IMAGE_LIST...
docker images | sort | fgrep daqf/ | fgrep latest | while read image tag hash other; do
    echo $image $hash >> inst/$DOCKER_IMAGE_LIST
done
echo Push images to update misc/$DOCKER_IMAGE_LIST

echo Updating .build_hash
bin/build_hash write
mv -f .build_files .build_built
